/**************************************************************************************************
**                                                                                               **
**  文件名称:  osl_msgman.c                                                                      **
**  版权所有:  CopyRight @ Xiamen Yaxon NetWork CO.LTD. 2017                                     **
**  文件描述:  系统消息管理模块                                                                  **
**  ===========================================================================================  **
**  创建信息:  | 2017-3-23 | LEON | 创建本模块                                                   **
**  ===========================================================================================  **
**  修改信息:  单击此处添加....                                                                  **
**************************************************************************************************/
#include "osl_include.h"
#include "osl_msg_man.h"

/*************************************************************************************************/
/*                           模块宏定义                                                          */
/*************************************************************************************************/
#define OS_MAX_MSG           10                                                /* 最大消息队列数 */

/*************************************************************************************************/
/*                           消息管理控制块定义                                                  */
/*************************************************************************************************/
typedef struct {
    INT16U      curpos;                                                        /* 当前处理到的位置 */
    INT16U      msgnum;                                                        /* 队列中的消息个数 */
    SYSMSG_T    msgbox[OS_MAX_MSG];                                            /* 消息块的具体内容 */
} MCB_T;

/*************************************************************************************************/
/*                           模块静态变量定义                                                    */
/*************************************************************************************************/
static MCB_T    s_msgcb;

/**************************************************************************************************
**  函数名称:  MsgIsExist
**  功能描述:  测试在消息队列中是否存在指定的消息ID
**  输入参数:  msgid: 消息ID
**  输出参数:  无
**  返回参数:  true-在消息队列中存在，false-不在消息队列中存在
**************************************************************************************************/
static BOOLEAN MsgIsExist(SYSMSG_ID_E msgid)
{
    INT16U pos, i;

    pos = s_msgcb.curpos;
    
    for (i = 0; i < s_msgcb.msgnum; i++, pos++) {
        
        if (pos >= OS_MAX_MSG) {
            pos -= OS_MAX_MSG;
        }
        
        if (s_msgcb.msgbox[pos].msgid == msgid) {
            return true;
        }
    }
    
    return false;
}

/**************************************************************************************************
**  函数名称:  OSL_SysMsg_Init
**  功能描述:  初始化函数
**  输入参数:  无
**  输出参数:  无
**  返回参数:  无
**************************************************************************************************/
void OSL_SysMsgInit(void)
{
    YX_MEMSET(&s_msgcb, 0, sizeof(s_msgcb));
}

/**************************************************************************************************
**  函数名称:  OSL_PostSysMsg
**  功能描述:  发送系统消息
**  输入参数:  msgid: 消息ID; para1: 消息参数1; para2: 消息参数2
**  输入参数:  overlay: 为true时，无条件发送该消息。为false时，先检查队列中，如果已有该消息则不发送
**  输出参数:  无
**  返回参数:  无
**************************************************************************************************/
void OSL_PostSysMsg(SYSMSG_ID_E msgid, INT32U para1, INT32U para2, BOOLEAN overlay)
{
    INT16U pos;
    
    SYS_ASSERT((s_msgcb.msgnum < OS_MAX_MSG), RETURN_VOID);
    
    if ((overlay == FALSE) && (MsgIsExist(msgid) == TRUE)) {                   /* 消息已存在，无需再次发送 */
        return;
    }
    
    pos = s_msgcb.curpos + s_msgcb.msgnum;
    
    if (pos >= OS_MAX_MSG) {
        pos -= OS_MAX_MSG;
    }
    
    s_msgcb.msgbox[pos].msgid = msgid;
    s_msgcb.msgbox[pos].para1 = para1;
    s_msgcb.msgbox[pos].para2 = para2;
    
    s_msgcb.msgnum++;
}

/**************************************************************************************************
**  函数名称:  OSL_PostSysMsgEx
**  功能描述:  投递消息，并且马上执行
**  输入参数:  无
**  输出参数:  无
**  返回参数:  无
**************************************************************************************************/
void OSL_PostSysMsgEx(SYSMSG_ID_E msgid, INT32U para1, INT32U para2, BOOLEAN overlay)
{
    OSL_PostSysMsg(msgid, para1, para2, overlay);
    SysMsgSchedEntry();
}

/**************************************************************************************************
**  函数名称:  SysMsgSchedEntry
**  功能描述:  系统消息统一处理入口【放在while循环中调用执行】
**  输入参数:  无
**  输出参数:  无
**  返回参数:  无
**************************************************************************************************/
void SysMsgSchedEntry(void)
{
    SYSMSG_ID_E msgid;
    INT32U      para1, para2;
    MSG_HDL_T   proc;
    
    for (;;) {
        
        if (s_msgcb.msgnum == 0) {
            break;
        }
        
        msgid = s_msgcb.msgbox[s_msgcb.curpos].msgid;
        para1 = s_msgcb.msgbox[s_msgcb.curpos].para1;
        para2 = s_msgcb.msgbox[s_msgcb.curpos].para2;

        proc = OSL_GetSysMsgHdl(msgid);

        if (proc != NULL) {
            proc(msgid, para1, para2);
        }
        
        if (++s_msgcb.curpos >= OS_MAX_MSG) {
            s_msgcb.curpos = 0;
        }
        
        s_msgcb.msgnum--;
    }
}

